/**
 * jQuery Hatenabookmark Entry Plugin
 *   http://code.google.com/p/jquery-hatenabookmark-entry/
 *
 * Copyright (c) 2009 Yusuke Horie
 *
 * Released under the MIT License:
 * http://www.opensource.org/licenses/mit-license.php
 *
 * Since  : 0.1.0 - 08/13/2009
 * Version: 0.1.0 - 08/13/2009
 */
(function(jQuery){

  var _baseUrl = 'http://b.hatena.ne.jp/entry/json/';

  /** public methods **/

  jQuery.fn.hatenaEntry = function (url, a) {
    var c, opts = {};
    if (jQuery.isFunction(a)) {
      c = a;
    } else if (typeof a == 'object') {
      opts = jQuery.extend({}, jQuery.fn.hatenaEntry.defaults, a);
      c = jQuery.isFunction(opts.callback) ? opts.callback: _callback;
    } else if (typeof a == 'undefined') {
      opts = jQuery.fn.hatenaEntry.defaults;
      c = _callback;
    } else {
      return this;
    }

    return this.each(function(i, e) {
      jQuery.getJSON(_baseUrl + '?url=' + encodeURIComponent(url) + '&callback=?',
        function (o) { c.apply(this, [o, e, opts]); }
      );
    });
  };

  jQuery.fn.hatenaEntry.defaults = {
    callback: null,
    icon: true,
    username: true,
    tags: true,
    comment: true,
    timestamp: true,
    headerBgColor: '#2C6EBD',
    headerColor: '#ffffff',
    userColor: '#0000DD',
    tagColor: '#6666cc',
    timeColor: '#666666',
    limit: 7,
    headerLabel: 'ブックマークしているユーザー'
  };

  jQuery.extend({
    hatenaEntry: function (url, a) {
      var c = jQuery.isFunction(a) ? a: _callback;
      jQuery.getJSON(_baseUrl + '?url=' + encodeURIComponent(url) + '&callback=?',
        function (o) {
          var args = [o];
          if (typeof a == 'string') args.push($(a).get());
          args.push(jQuery.fn.hatenaEntry.defaults);
          c.apply(this, args);
        });
    }
  });

  /** private method **/

  var _callback = function (o, e, opts) {
    var $this = $(e);
    if (!o || $this.length == 0) return false;
    $this.data('_inc', 1);

    var h =
      '<div style="padding:5px;background-color:' + opts.headerBgColor + ';color:' + opts.headerColor + ';">' +
      ' <span style="font-weight:bold;font-size:120%;">' + opts.headerLabel + '</span> (' + o.count + ')' +
      '</div>'+
      '<div class="hbEntryContainer">' + _build(o, $this, opts) + '</div>';
    $this.html(h);

    $('a.hbEntryShow').live('click.hbEntryShow', function (event) {
      event.preventDefault();
      var $t = $(this);

      $t.parent().fadeOut(400, function () {
        var i = $this.data('_inc');
        i++;
        $this.data('_inc', i);

        if ($t.hasClass('hbEntryAll')) {
          $t.die('click.hbEntryShow');
          var start = (i*opts.limit) - opts.limit;
          var end = o.bookmarks.length;
          $(this).after(_build(o, $this, opts, start, end)).remove();
        } else {
          $(this).after(_build(o, $this, opts)).remove();
        }
      });
    });

  };

  var _build = function (o, $t, opts, s, e) {
    var
      h = '',
      inc = $t.data('_inc'),
      start = s || (inc*opts.limit) - opts.limit,
      end = e || ((o.bookmarks.length > start + opts.limit) ? start + opts.limit: o.bookmarks.length);

    for (var i=start; i<end; i++) {
      var b = o.bookmarks[i];
      h +=
        '<div style="padding:5px 0;">';
      if (opts.icon)
        h += 
          ' <img src="http://www.st-hatena.com/users/sk/' + b.user + '/profile_s.gif" ' +
          'alt="' + b.user + '" title="' + b.user + '" width="16" height="16" style="vertical-align:middle;" />';
      if (opts.username)
        h += ' <a href="http://b.hatena.ne.jp/' + b.user + '/" style="color:' + opts.userColor + ';">' + b.user + '</a>';
      if (opts.tags)
        h +=' <span style="color:' + opts.tagColor + ';font-size:90%;">' + b.tags.join(' ') + '</span>';
      if (opts.comment)
        h += ' <span>' + b.comment + '</span>';
      if (opts.timestamp)
        h += ' <span style="color:' + opts.timeColor + ';font-size:90%;">' + b.timestamp.split(' ')[0] + '</span>';
      h += '</div>';
    }

    if (o.bookmarks.length > end) {
      h +=
        '<div style="text-align:center;padding:5px;border:solid 1px #ccc;">' +
        '<a href="#" class="hbEntryShow">次の' + opts.limit + ' 件を開く</a> &nbsp;/&nbsp;' +
        '<a href="#" class="hbEntryShow hbEntryAll">すべて開く</a>' +
        '</div>';
    }
    return h;
  };

})(jQuery);